import { message } from 'antd';
import React, { useCallback, useState }from 'react';

export const useUpdate = (): [number, () => void] => {
  const [it, setIt] = useState<number>(Date.now());
  const update = useCallback(() => setIt(Date.now()), []);
  return [it, update];
};


/**
 * 表格数据钩子
 * @param param0 配置参数
 * @returns 表格数据相关状态和方法
 */
const useTable = <T,>({
  api,
  searchParams,
  immediate = true,
}: UseTable.IUseTableParams<T>): UseTable.IUseTableReturn<T> => {
  const isFirst = React.useRef(true);
  const [data, setData] = React.useState<UseTable.ITableData<T>>({
    list: [],
    total: 0,
  });
  const [isLoading, setIsLoading] = React.useState<boolean>(false);
  const [_searchParams, _setSearchParams] =
    React.useState<UseTable.ISearchParams>(searchParams || {});
  const [_refresh, setRefresh] = useUpdate();

  const fetchList = async () => {
    setIsLoading(true);
    api(_searchParams)
      .then((res: any) => {
        console.log(res, 'table');

        const { list = [], total = 0 } = res;
        setData({ list, total });
      })
      .catch((err) => {
        message.error(err.message || '获取数据失败');
        console.error(err);
      })
      .finally(() => {
        setIsLoading(false);
      });
  };

  /** 设置搜索参数并刷新列表， 支持react setstate 语法 */
  const setSearchParams: React.Dispatch<
    React.SetStateAction<UseTable.ISearchParams>
  > = (newValue: React.SetStateAction<UseTable.ISearchParams>) => {
    _setSearchParams((prev) => {
      const newParams =
        typeof newValue === 'function' ? newValue(prev) : newValue;
      return { ...prev, ...newParams };
    });
    setRefresh();
  };

  React.useEffect(() => {
    if (immediate && isFirst.current) {
      fetchList();
      isFirst.current = false;
    } else {
      fetchList();
    }
  }, [_refresh]);

  return {
    data,
    setData,
    refresh: setRefresh,
    isLoading,
    searchParams: _searchParams,
    setSearchParams,
  };
};

export default useTable;
